from threading import Thread, RLock,Timer
import time

# l1=Lock()
# l2=Lock()
#
# def fun():
#     l1.acquire()
#     print("l1上锁")
#     time.sleep(1)
#     l2.acquire()
#     print("l2上锁")
#
#     l1.release()
#     print("l1解锁")
#
#     l2.release()
#     print("l2解锁")
#
#
# def fun2():
#     l2.acquire()
#     print("l2上锁")
#
#     l1.acquire()
#     print("l1上锁")
#
#     l2.release()
#     print("l2解锁")
#
#     l1.release()
#     print("l1解锁")
#
#
#
# if __name__ == '__main__':
#     Thread(target=fun).start()
#     Thread(target=fun2).start()

# l1=l2=RLock()
#
# def fun():
#     l1.acquire()
#     print("l1上锁")
#     time.sleep(1)
#     l2.acquire()
#     print("l2上锁")
#
#     l1.release()
#     print("l1解锁")
#
#     l2.release()
#     print("l2解锁")
#
#
# def fun2():
#     l2.acquire()
#     print("l2上锁")
#
#     l1.acquire()
#     print("l1上锁")
#
#     l2.release()
#     print("l2解锁")
#
#     l1.release()
#     print("l1解锁")
#
#
#
# if __name__ == '__main__':
#     t1=Thread(target=fun)
#     t2=Thread(target=fun2)
#     t1.start()
#     t2.start()
#     t1.join()
#     t2.join()

# def fun():
#     print(time.strftime("%Y-%m-%d %H:%M:%S"))
#
# if __name__ == '__main__':
#     print(time.strftime("%Y-%m-%d %H:%M:%S"))
#     Timer(3,fun).start()
# from threading import Thread, Lock
# import time
#
# # 创建两把锁
# l1 = Lock()
# l2 = Lock()
#
# def fun1():
#     # 加锁
#     l1.acquire()
#     print('函数1 添加了锁1')
#     time.sleep(1)
#     l2.acquire()
#     # 解锁
#     l1.release()
#     print('函数1 添加了锁2')
#     l2.release()
#
#
# def fun2():
#     # 加锁
#     l2.acquire()
#     print('函数2 添加了锁2')
#     l1.acquire()
#     # 解锁
#     l2.release()
#     print('函数2 添加了锁1')
#     l1.release()
#
# # 创建线程
# t1 = Thread(target=fun1)
# t2 = Thread(target=fun2)
# # 开启线程
# t1.start()
# t2.start()
#
# t1.join()
# t2.join()

# from threading import Thread, Lock, RLock
# import time
#
# # 创建递归锁只能是一个锁对象
# l1 = l2 = RLock()
#
#
# def fun1():
#     # 加锁
#     l1.acquire()
#     print('函数1 添加了锁1')
#     time.sleep(1)
#     l2.acquire()
#     # 解锁
#     l1.release()
#     print('函数1 添加了锁2')
#     l2.release()
#
#
# def fun2():
#     # 加锁
#     l2.acquire()
#     print('函数2 添加了锁2')
#     l1.acquire()
#     # 解锁
#     l2.release()
#     print('函数2 添加了锁1')
#     l1.release()
#
#
# t1 = Thread(target=fun1)
# t2 = Thread(target=fun2)
#
# t1.start()
# t2.start()
#
# t1.join()
# t2.join()

# from threading import Timer
# import time
#
#
# def fun1(name):
#     print('炸弹引爆的时间：')
#     print(time.strftime("%Y-%m-%d %H:%M:%S"))
#     print({name})
#
#
# if __name__ == '__main__':
#     print('炸弹埋下的时间：')
#     print(time.strftime("%Y-%m-%d %H:%M:%S"))
#     # 创建定时器并开启
#     # Timer(定时秒数, 定时结束需要执行的函数, 元祖类型的参数)
#     Timer(3, fun1, ('石头', )).start()

# from threading import Thread, Event
# import time
# import random
#
#
# # 红绿灯
# def fun1():
#     while True:
#         # 恢复Event状态值为false
#         e.clear()
#         print('红灯静止通行')
#         # 设置红灯时间为3秒
#         time.sleep(3)
#         # 3秒后绿灯亮起，Event状态值为true
#         e.set()
#         print('绿灯亮了，请尽快通行')
#         time.sleep(2)
#
#
# # 设置行人
# def fun2(name):
#     while True:
#         # 判断当前是否可以通行
#         if e.is_set():
#             print(f'行人{name}正在经过斑马线')
#             break
#         else:
#             print(f'现在是红灯，请{name}等待')
#             e.wait()
#
#
# if __name__ == '__main__':
#     # 创建Event对象
#     e = Event()
#     # 设置红绿灯启动的线程
#     Thread(target=fun1).start()
#
#     # 创建行人
#     list = ['石头', '执笔划余生', '德哈卡', 'QAQ', '小渡']
#
#     for i in list:
#         # 模拟人走到红绿灯前面
#         time.sleep(random.randint(0, 3))
#         Thread(target=fun2, args=(i,)).start()
# from concurrent.futures import ProcessPoolExecutor
# import time
# pool_p = ProcessPoolExecutor(1)
# def fun(i):
#     print(i)
#     time.sleep(1)
#
#
# if __name__ == '__main__':
#     for i in range(20):
#         pool_p.submit(fun,i+1)
'''
    submit（任务【函数】， 参数）该方法是有返回值的，返回的是一个Future对象
    通过Future对象来获取到返回值，使用result（）
'''
# from concurrent.futures import ProcessPoolExecutor
# import time
#
# # 设置进程池对象， 传入参数，这个参数代表了这个进程池的大小（多少个进程）
# # 若没有参数的话，会默认开始与当前电脑cpu核数相匹配的进程个数
# pool_p = ProcessPoolExecutor(5)
#
#
# def fun(name, num):
#     print(f'{name}今天很帅')
#     time.sleep(2)
#     return num + 1
#
#
# if __name__ == '__main__':
#     for i in range(20):
#         # 进程池对象.submit（任务【函数】， 参数）
#         # 任务参数有多个 ， 那么按照位置参数的要求进行传参
#         # Future对象获取到的值就是我们执行任务的返回值
#         res = pool_p.submit(fun, f'石头{i + 1}号', i + 1)
#         # 通过result方法可以获取到Future对象的值
#         print(f'您的年龄是：{res.result()}')


#     shutdown() 等待进程池中所有进程任务结束之后 ， 再执行主进程
# '''
# from concurrent.futures import ProcessPoolExecutor
# import time
#
# # 设置进程池对象， 传入参数，这个参数代表了这个进程池的大小（多少个进程）
# # 若没有参数的话，会默认开始与当前电脑cpu核数相匹配的进程个数
# pool_p = ProcessPoolExecutor(5)
#
#
# def fun(name, num):
#     print(f'{name}今天很帅')
#     time.sleep(2)
#     return num + 1
#
#
# if __name__ == '__main__':
#
#     # 将所有任务的返回值放入列表中
#     list = []
#     for i in range(20):
#         # 进程池对象.submit（任务【函数】， 参数）
#         # 任务参数有多个 ， 那么按照位置参数的要求进行传参
#         # Future对象获取到的值就是我们执行任务的返回值
#         res = pool_p.submit(fun, f'石头{i + 1}号', i + 1)
#         list.append(res)
#     # 等到进程池中的任务全部执行完毕
#     pool_p.shutdown()
#     for i in list:
#         print(i.result())'''

# '''
#     进程池有一个回调机制 —— add_done_callback()
# '''
# from concurrent.futures import ProcessPoolExecutor
# import time
#
# # 设置进程池对象， 传入参数，这个参数代表了这个进程池的大小（多少个进程）
# # 若没有参数的话，会默认开始与当前电脑cpu核数相匹配的进程个数
# pool_p = ProcessPoolExecutor(5)
#
#
# def fun(num):
#     return num + 1
#
# # 处理任务的返回值
# def get(f):
#     print(f'获取返回值结果{f.result()}')
#
#
# if __name__ == '__main__':
#
#     for i in range(20):
#         # 进程池对象.submit（任务【函数】， 参数）
#         # 任务参数有多个 ， 那么按照位置参数的要求进行传参
#         # Future对象获取到的值就是我们执行任务的返回值
#         res = pool_p.submit(fun, i + 1)
#         # 回调机制不需要对任务进行参数传递 ， 参数会根据Future对象进行传入
#         # 需要及时获取到Future对象的返回值的时候 ， 就可以使用回调机制进行获取。
#         # 统一对数据进行处理
#         res.add_done_callback(get)

# from concurrent.futures import ThreadPoolExecutor
# import time
#
# # 创建线程池对象
# t = ThreadPoolExecutor(10)
#
#
# def fun(name):
#     print(f'{name}正在投篮')
#     time.sleep(1)
#     return 'hello'
#
#
# def get(f):
#     print(f'获取返回值结果{f.result()}')
#
#
# if __name__ == '__main__':
#     for i in range(20):
#         # 进程池对象.submit（任务【函数】， 参数）
#         # 任务参数有多个 ， 那么按照位置参数的要求进行传参
#         res = t.submit(fun, f'石头{i + 1}号')
#         res.add_done_callback(get)
